package com.leyou.search.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.*;
import com.leyou.search.entity.Goods;
import com.leyou.search.service.IGoodsService;
import com.leyou.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

@Service
public class GoodsServiceImpl implements IGoodsService {

    @Autowired
    private ItemClient itemClient;

    /**
     * 导入数据到elasticsearch
     * 通过Spu查询Goods
     *
     * @param spuDTO
     * @return
     */
    @Override
    public Goods buildGoods(SpuDTO spuDTO) {
        //1.搜索框条件
        //1.1.category三级的name
        String categoryNames = itemClient.queryCategoryByIds(spuDTO.getCategoryIds()).stream()
                .map(CategoryDTO::getName).collect(Collectors.joining(","));
        //1.2.brand的name
        String brandName = itemClient.queryBrandById(spuDTO.getBrandId()).getName();
        //1.3.合并搜索条件   spuName+categoryName+BrandName
        String all = spuDTO.getName() + categoryNames + brandName;
        //2.所有sku的map集合
        List<Map<String, Object>> skuList = new ArrayList<>();
        //2.1.获取所有的sku
        List<SkuDTO> skuDTOS = spuDTO.getSkus() == null ? itemClient.querySkuBySpu(spuDTO.getId()) : spuDTO.getSkus();
        //2.2.将所有的sku放进map集合中
        skuDTOS.stream().forEach(skuDTO -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", skuDTO.getId());
            map.put("title", skuDTO.getTitle());
            //取第一个图片地址(第一个逗号之前的image地址)
            map.put("images", StringUtils.substringBefore(skuDTO.getImages(), ","));
            map.put("price", skuDTO.getPrice());
            skuList.add(map);
        });
        //2.3.将所有sku的map集合转化为string
        String skus = JsonUtils.toString(skuList);
        //3.所有sku价格的集合
        Set<Long> prices = skuDTOS.stream().map(SkuDTO::getPrice).collect(Collectors.toSet());
        //4.规格参数
        //4.1.获取规格参数的key
        List<SpecParamDTO> specParamDTOS = itemClient.querySpecParams(null, spuDTO.getCid3(), true);
        //4.2.获取规格参数的value
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail() == null ? itemClient.querySpuDetailBySpu(spuDTO.getId()) : spuDTO.getSpuDetail();
        //4.2.1.通用属性generic_spec转换为map
        String genericSpec = spuDetailDTO.getGenericSpec();
        Map<Long, Object> genericSpecMap = JsonUtils.toMap(genericSpec, Long.class, Object.class);
        //4.2.2.特有属性special_spec转换为map
        String specialSpec = spuDetailDTO.getSpecialSpec();
        Map<Long, List<Object>> specialSpecMap = JsonUtils.nativeRead(specialSpec, new TypeReference<Map<Long, List<Object>>>() {
        });
        //4.3.设置params的key和value
        Map<String, Object> map = new HashMap<>();
        for (SpecParamDTO specParamDTO : specParamDTOS) {
            //4.3.1设置params的key
            String key = specParamDTO.getName();
            Object value;
            if (specParamDTO.getGeneric()) {
                //如果是通用param
                value = genericSpecMap.get(specParamDTO.getId());
            } else {
                //如果是特有param
                value = specialSpecMap.get(specParamDTO.getId());
            }
            if (specParamDTO.getNumeric()) {
                //如果是数值类型,进行分段
                value = chooseSegment(value, specParamDTO);
            }
            map.put(key, value);
        }

        Goods goods = new Goods();
        goods.setId(spuDTO.getId());   // spu的id
        goods.setAll(all);   //  搜索条件(spuName+categoryName+BrandName)
        goods.setBrandId(spuDTO.getBrandId());   //品牌的id
        goods.setCategoryId(spuDTO.getCid3());   //第三级分类id
        goods.setCreateTime(spuDTO.getCreateTime().getTime());   //spu创建的时间
        goods.setSkus(skus);   //   所有sku的map集合的list集合
        goods.setPrice(prices);   //  所有sku价格的集合
        goods.setSpecs(map);   //  规格参数
        goods.setSubTitle(spuDTO.getSubTitle());   //spu的副标题
        return goods;
    }

    /**
     * 将数值类型的进行分段
     *
     * @param value
     * @param p
     * @return
     */
    private String chooseSegment(Object value, SpecParamDTO p) {
        if (value == null || StringUtils.isBlank(value.toString())) {
            return "其它";
        }
        double val = parseDouble(value.toString());
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = parseDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if (segs.length == 2) {
                end = parseDouble(segs[1]);
            }
            // 判断是否在范围内
            if (val >= begin && val < end) {
                if (segs.length == 1) {
                    result = segs[0] + p.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segs[1] + p.getUnit() + "以下";
                } else {
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }

    private double parseDouble(String str) {
        try {
            return Double.parseDouble(str);
        } catch (Exception e) {
            return 0;
        }
    }
}
